home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 30
/
Aminet 30 (1999)(Schatztruhe)[!][Apr 1999].iso
/
Aminet
/
misc
/
math
/
MathFX_src.lha
/
fxnxtv.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-12-20
|
8KB
|
264 lines
/* Draws the next view of a 3-d plot. The physical coordinates of */
/* the points for the next view are placed in the n points of arrays */
/* u and v. The silhouette found so far is stored in the heap as a */
/* set of m peak points. */
/* Define the heap size. This can be increased if necessary. Someday */
/* I hope to just allocate a heap space of minimum required size. */
#define heaps 15000
#include <stdio.h>
#include <stdlib.h>
#include "mathfx.h"
#include "declare.h"
static int m, x, y;
void fxnxtv(u,v,n,init)
int u[], v[], n, init;
{
int xx;
int i, j, first;
int sx1, sx2, sy1, sy2;
int su1, su2, sv1, sv2;
int cx, cy, px, py;
int seg, ptold, lstold, pthi, pnewhi, newhi, change, ochange;
first = 1;
pnewhi = 0;
/* For the initial set of points, just disfxay them and store them as */
/* the peak points. */
if (init == 1) {
if( heap3 == NULL) /* heap not yet allocated so ... */
if(( heap3 = (int *)malloc(heaps*sizeof(int))) == NULL)
fatal("Not enough heap space in FXNXTV.");
y = heaps - n;
x = y - n;
movphy(u[0],v[0]);
heap3[x] = u[0];
heap3[y] = v[0];
for (i=1; i<n; i++){
draphy(u[i],v[i]);
heap3[x+i] = u[i];
heap3[y+i] = v[i];
}
m = n;
return;
}
/* Otherwise, we need to consider hidden-line removal problem. We scan */
/* over the points in both the old (i.e. heap3[x...] and heap3[y...]) and */
/* new (i.e. u[] and v[]) arrays in order of increasing x coordinate. */
/* At each stage, we find the line segment in the other array (if one */
/* exists) that straddles the x coordinate of the point. We */
/* have to determine if the point lies above or below the line segment, */
/* and to check if the below/above status has changed since the last */
/* point. */
/* If init = 2 we do not update the view, this is useful for drawing */
/* lines on the graph after we are done fxotting points. Hidden line */
/* removal is still done, but the view is not updated. */
xx = 0;
i = 0;
j = 0;
/* (heap3[x+i], heap3[y+i]) is the i'th point in the old array */
/* (u[j], v[j]) is the j'th point in the new array */
while (i < m || j < n) {
/* The coordinates of the point under consideration are (px,py). */
/* The line segment joins (sx1,sy1) to (sx2,sy2). */
/* "ptold" is true if the point lies in the old array. We set it */
/* by comparing the x coordinates of the i'th old point */
/* and the j'th new point, being careful if we have fallen past */
/* the edges. Having found the point, load up the point and */
/* segment coordinates appropriately. */
ptold = ((heap3[x+i] < u[j] && i<m) || j>= n);
if (ptold) {
px = heap3[x+i];
py = heap3[y+i];
seg = j>0 && j<n;
if (seg) {
sx1 = u[j-1];
sy1 = v[j-1];
sx2 = u[j];
sy2 = v[j];
}
}
else {
px = u[j];
py = v[j];
seg = i>0 && i<m;
if (seg) {
sx1 = heap3[x+i-1];
sy1 = heap3[y+i-1];
sx2 = heap3[x+i];
sy2 = heap3[y+i];
}
}
/* Now determine if the point is higher than the segment, using the */
/* logical function "above". We also need to know if it is */
/* the old view or the new view that is higher. "newhi" is set true */
/* if the new view is higher than the old */
if(seg)
pthi = fxabv(px,py,sx1,sy1,sx2,sy2);
else
pthi = 1;
newhi = (ptold && !pthi) || (!ptold && pthi);
change = (newhi && !pnewhi) || (!newhi && pnewhi);
/* There is a new intersection point to put in the peak array if the */
/* state of "newhi" changes */
if (first) {
movphy(px,py);
first = 0;
lstold = ptold;
if (init != 2) {
heap3[xx] = px;
heap3[xx+1] = py;
xx = xx + 2;
}
pthi = 0;
ochange = 0;
}
else if (change) {
/* Take care of special cases at end of arrays. If init is 2 the */
/* endpoints are not connected to the old view. */
if (init==2 && ((!ptold && j==0)||(ptold && i==0))) {
movphy(px,py);
lstold = ptold;
pthi = 0;
ochange = 0;
}
else if (init==2 && ((!ptold && i>=m)||(ptold && j>=n))) {
movphy(px,py);
lstold = ptold;
pthi = 0;
ochange = 0;
}
/* If init is not 2 then we do want to connect the current line */
/* with the previous view at the endpoints. */
/* Also find intersection point with old view. */
else {
if (i == 0) {
sx1 = heap3[x];
sy1 = -1;
sx2 = heap3[x];
sy2 = heap3[y];
}
else if (i >= m) {
sx1 = heap3[x+m-1];
sy1 = heap3[y+m-1];
sx2 = heap3[x+m-1];
sy2 = -1;
}
else {
sx1 = heap3[x+i-1];
sy1 = heap3[y+i-1];
sx2 = heap3[x+i];
sy2 = heap3[y+i];
}
if (j == 0) {
su1 = u[0];
sv1 = -1;
su2 = u[0];
sv2 = v[0];
}
else if (j >= n) {
su1 = u[n-1];
sv1 = v[n-1];
su2 = u[n];
sv2 = -1;
}
else {
su1 = u[j-1];
sv1 = v[j-1];
su2 = u[j];
sv2 = v[j];
}
/* Determine the intersection */
fx3cut(sx1,sy1,sx2,sy2,su1,sv1,su2,sv2,&cx,&cy);
if (cx == px && cy == py) {
if (lstold && !ochange)
movphy(px,py);
else
draphy(px,py);
if (init != 2) {
heap3[xx] = px;
heap3[xx+1] = py;
xx = xx+2;
}
lstold = 1;
pthi = 0;
}
else {
if (lstold && !ochange)
movphy(cx,cy);
else
draphy(cx,cy);
lstold = 1;
if (init != 2) {
heap3[xx] = cx;
heap3[xx+1] = cy;
xx = xx+2;
}
}
ochange =1;
}
}
/* If point is high then draw fxot to point and update view. */
if (pthi) {
if (lstold && ptold)
movphy(px,py);
else
draphy(px,py);
if (init != 2) {
heap3[xx] = px;
heap3[xx+1] = py;
xx = xx+2;
}
lstold = ptold;
ochange = 0;
}
pnewhi = newhi;
if (ptold)
i = i+1;
else
j = j+1;
if (xx>=x) fatal("Heap overflow in fxnxtv.");
}
/* Transfer the peak points to the RHS of the heap */
if(init != 2) {
m = xx/2;
xx = 0;
y = heaps - m;
x = y - m;
for(i=0; i<m; i++) {
heap3[x+i] = heap3[xx];
heap3[y+i] = heap3[xx+1];
xx = xx+2;
}
}
}